# -*- coding: utf-8 -*-
"""
01. Python 变量和数据类型 - Java工程师学习指南

=== 概述 ===
Python是动态类型语言，与Java的静态类型有本质区别：
- Java: 编译时确定类型，运行时不可改变
- Python: 运行时确定类型，可以动态改变

=== 本章学习重点 ===
1. 理解Python的动态类型系统 vs Java静态类型
2. 掌握类型注解的使用（类似Java的类型声明，但不强制）
3. 学习Python的数据验证机制
4. 了解Python的语法糖和高级特性

=== Java对比 ===
Java写法：
    int age = 25;           // 编译时类型检查
    String name = "John";   // 类型不可改变
    
Python写法：
    age: int = 25          # 类型注解（可选，不强制）
    name: str = "John"     # 运行时可以改变类型
    age = "twenty-five"    # 合法！类型动态改变
"""

# === 导入说明（对Java工程师） ===
from typing import List, Dict, Set, Tuple, Optional, Union, Any  # 类型注解，类似Java的泛型
from dataclasses import dataclass # 数据类装饰器，类似Lombok的@Data
from enum import Enum             # 枚举类型，类似Java的enum
import logging                    # 日志系统，类似Java的slf4j

# === 日志配置（类似Java的logback配置） ===
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 企业级常量定义（使用大写命名）
MAX_ITEMS: int = 100
DEFAULT_ENCODING: str = "utf-8"
API_VERSION: str = "v1.0"

# === 枚举类定义（对比Java enum） ===
# Java等价写法：
# public enum Status {
#     ACTIVE("active"),
#     INACTIVE("inactive"),
#     PENDING("pending");
#     
#     private final String value;
#     Status(String value) { this.value = value; }
# }
class Status(Enum):
    """状态枚举 - Python的枚举比Java更简洁"""
    ACTIVE = "active"        # 直接赋值，无需构造函数
    INACTIVE = "inactive"
    PENDING = "pending"

# === @dataclass 装饰器详解（对比Java Bean） ===
# Java Bean等价写法需要大量样板代码：
# public class UserProfile {
#     private String name;
#     private int age;
#     private String email;
#     private boolean isActive = true;
#     
#     // 构造函数
#     public UserProfile(String name, int age, String email) { ... }
#     
#     // Getter和Setter方法（约20行代码）
#     public String getName() { return name; }
#     public void setName(String name) { this.name = name; }
#     // ... 其他getter/setter
#     
#     // equals, hashCode, toString方法（约30行代码）
# }

@dataclass  # 这个装饰器自动生成：__init__, __repr__, __eq__, __hash__等方法
class UserProfile:
    """用户配置数据类 - 相当于Java Bean + Lombok的@Data注解"""
    name: str                    # 必需字段，类似Java的private String name
    age: int                     # 必需字段，类似Java的private int age
    email: Optional[str] = None  # 可选字段，类似Java的private String email
    is_active: bool = True       # 默认值字段，类似Java的private boolean isActive = true
    
    def __post_init__(self):
        """数据类后处理 - 类似Java Bean Validation
        
        Java等价写法：
        @PostConstruct
        public void validate() {
            if (age < 0 || age > 150) {
                throw new IllegalArgumentException("年龄必须在0-150之间");
            }
        }
        """
        if self.age < 0 or self.age > 150:
            raise ValueError("年龄必须在0-150之间")
        if self.email and '@' not in self.email:
            raise ValueError("邮箱格式不正确")

def demonstrate_basic_types() -> None:
    """演示基础数据类型 - 对比Java的类型系统
    
    🎯 概述引导：
    这是Python学习的第一步，重点理解Python的动态类型系统与Java静态类型的根本差异。
    
    📚 学习要点：
    1. Python的类型注解只是提示，不强制执行（Java编译时强制）
    2. Python变量可以在运行时改变类型（Java不允许）
    3. Python的复杂数据类型更灵活（List、Dict、Set）
    4. 理解何时使用类型注解来提高代码质量
    
    🔍 Java对比：
    public void demonstrateBasicTypes() {
        int userId = 10;           // 编译时类型检查，不可改变
        double price = 3.14;       // 基本类型
        String username = "Hello"; // 引用类型
        boolean isAuth = true;     // 基本类型
    }
    
    💡 关键理解：
    Python的类型注解是为了代码可读性和IDE支持，而不是强制约束。
    这与Java的强类型系统形成鲜明对比。
    """
    print("\n======== 1. 企业级变量和数据类型最佳实践 ========")
    print("🎯 学习目标：理解Python动态类型 vs Java静态类型的核心差异")
    print("📖 重点概念：类型注解、动态类型、复杂数据结构")
    print("-" * 60)
    
    # === 基础类型注解（类似Java的类型声明，但不强制） ===
    user_id: int = 10                    # 类型注解，类似Java的 int userId = 10
    price: float = 3.14                  # 浮点数，类似Java的 double price = 3.14
    username: str = "Hello, Python"      # 字符串，类似Java的 String username = "Hello"
    is_authenticated: bool = True        # 布尔值，类似Java的 boolean isAuth = true
    
    # === Python的动态类型特性（Java不支持） ===
    # 在Java中，以下操作会编译错误：
    # userId = "not a number";  // 编译错误！
    # 但在Python中是合法的（虽然不推荐）：
    # user_id = "not a number"  # 运行时类型改变，合法但不推荐
    
    # === 复杂数据类型的类型注解（对比Java泛型） ===
    # Java等价写法：
    # List<Integer> userScores = Arrays.asList(95, 87, 92, 88);
    # Map<String, Object> userConfig = new HashMap<>();
    # Set<String> tags = new HashSet<>();
    # Optional<String> description = Optional.empty();
    
    user_scores: List[int] = [95, 87, 92, 88]  # 类似Java的 List<Integer>
    coordinates: Tuple[float, float] = (40.7128, -74.0060)  # 元组，Java没有直接等价物
    user_config: Dict[str, Union[str, int, bool]] = {  # 类似Java的 Map<String, Object>
        "theme": "dark",
        "notifications": True,
        "max_connections": 10
    }
    unique_tags: Set[str] = {"python", "enterprise", "best-practices"}  # 类似Java的 Set<String>
    optional_description: Optional[str] = None  # 类似Java的 Optional<String>
    
    print(f"用户ID (int): {user_id}, 类型: {type(user_id)}")
    print(f"价格 (float): {price}, 类型: {type(price)}")
    print(f"用户名 (str): '{username}', 类型: {type(username)}")
    print(f"认证状态 (bool): {is_authenticated}, 类型: {type(is_authenticated)}")
    print(f"用户分数 (List[int]): {user_scores}, 类型: {type(user_scores)}")
    print(f"坐标 (Tuple[float, float]): {coordinates}, 类型: {type(coordinates)}")
    print(f"用户配置 (Dict): {user_config}, 类型: {type(user_config)}")
    print(f"标签集合 (Set[str]): {unique_tags}, 类型: {type(unique_tags)}")
    print(f"可选描述 (Optional[str]): {optional_description}, 类型: {type(optional_description)}")

def demonstrate_advanced_operations() -> None:
    """演示高级数据操作：解包、切片、推导式等"""
    print("\n======== 2. 高级数据操作和语法糖 ========")
    
    # 序列解包（Unpacking）
    numbers: List[int] = [1, 2, 3, 4, 5]
    first, *middle, last = numbers
    print(f"解包操作: first={first}, middle={middle}, last={last}")
    
    # 字典解包
    base_config: Dict[str, Any] = {"debug": True, "timeout": 30}
    extended_config: Dict[str, Any] = {**base_config, "retries": 3, "timeout": 60}
    print(f"字典解包: {extended_config}")
    
    # 切片操作（Slicing）
    data: List[int] = list(range(10))
    print(f"原始数据: {data}")
    print(f"前3个元素: {data[:3]}")
    print(f"后3个元素: {data[-3:]}")
    print(f"步长为2: {data[::2]}")
    print(f"反转: {data[::-1]}")
    
    # 列表推导式和生成器表达式
    squares: List[int] = [x**2 for x in range(5)]
    even_squares: List[int] = [x**2 for x in range(10) if x % 2 == 0]
    print(f"平方数列表: {squares}")
    print(f"偶数平方: {even_squares}")
    
    # 字典推导式
    word_lengths: Dict[str, int] = {word: len(word) for word in ["python", "enterprise", "best"]}
    print(f"单词长度字典: {word_lengths}")

def validate_data(value: Any, expected_type: type, field_name: str) -> bool:
    """数据验证函数
    
    Args:
        value: 要验证的值
        expected_type: 期望的类型
        field_name: 字段名称
        
    Returns:
        bool: 验证是否通过
        
    Raises:
        TypeError: 当类型不匹配时
    """
    if not isinstance(value, expected_type):
        error_msg = f"{field_name} 期望类型 {expected_type.__name__}, 实际类型 {type(value).__name__}"
        logger.error(error_msg)
        raise TypeError(error_msg)
    return True

def demonstrate_data_validation() -> None:
    """演示数据验证最佳实践"""
    print("\n======== 3. 数据验证和错误处理 ========")
    
    try:
        # 正确的数据验证
        user_age: int = 25
        validate_data(user_age, int, "user_age")
        print(f"✓ 用户年龄验证通过: {user_age}")
        
        # 使用数据类
        user = UserProfile(name="张三", age=30, email="zhangsan@example.com")
        print(f"✓ 用户配置创建成功: {user}")
        
        # 枚举使用
        current_status = Status.ACTIVE
        print(f"✓ 当前状态: {current_status.value}")
        
    except TypeError as e:
        logger.error(f"数据验证失败: {e}")
    except Exception as e:
        logger.error(f"未预期的错误: {e}")

def demonstrate_type_checking() -> None:
    """演示运行时类型检查 - 对比Java的编译时检查
    
    Java对比：
    Java在编译时就会检查类型，而Python需要运行时检查
    public String processUserData(int userId, Map<String, Object> metadata) {
        // Java编译器自动保证类型正确，无需手动检查
        return "处理用户 " + userId + " 的数据: " + metadata;
    }
    """
    print("\n======== 4. 运行时类型检查 ========")
    
    def process_user_data(user_id: int, metadata: Dict[str, Any]) -> str:
        """处理用户数据的类型安全函数
        
        注意：Python的类型注解只是提示，不会强制执行
        需要手动进行运行时类型检查（Java编译时自动检查）
        """
        # === 运行时类型检查（Java编译时自动完成） ===
        assert isinstance(user_id, int), f"user_id 必须是 int 类型，实际: {type(user_id)}"
        assert isinstance(metadata, dict), f"metadata 必须是 dict 类型，实际: {type(metadata)}"
        
        return f"处理用户 {user_id} 的数据: {metadata}"
    
    def validate_user_data(user_id: int, email: str, age: int) -> bool:
        """验证用户数据的类型和有效性
        
        注意：Python的类型注解只是提示，不会强制执行
        需要手动进行运行时类型检查（Java编译时自动完成）
        """
        # === 运行时类型检查（Java编译时自动完成） ===
        if not isinstance(user_id, int):  # Java: 编译器自动检查
            raise TypeError(f"用户ID必须是整数，得到: {type(user_id)}")
        if not isinstance(email, str):    # Java: 编译器自动检查
            raise TypeError(f"邮箱必须是字符串，得到: {type(email)}")
        if not isinstance(age, int):      # Java: 编译器自动检查
            raise TypeError(f"年龄必须是整数，得到: {type(age)}")
        
        # === 业务逻辑验证（Java和Python类似） ===
        if user_id <= 0:
            raise ValueError("用户ID必须大于0")
        if '@' not in email:
            raise ValueError("邮箱格式无效")
        if not 0 <= age <= 150:
            raise ValueError("年龄必须在0-150之间")
        
        return True
    
    # 正确使用
    result = process_user_data(123, {"role": "admin", "last_login": "2024-01-01"})
    print(f"✓ {result}")
    
    # 类型验证测试
    try:
        validate_user_data(123, "test@example.com", 25)
        print("✓ 用户数据验证通过")
    except (TypeError, ValueError) as e:
        print(f"✗ 用户数据验证失败: {e}")

def run_comprehensive_tests() -> None:
    """运行全面的测试套件"""
    print("\n======== 5. 综合测试 ========")
    
    test_cases = [
        (123, int, "整数测试"),
        (3.14, float, "浮点数测试"),
        ("test", str, "字符串测试"),
        (True, bool, "布尔值测试"),
        ([1, 2, 3], list, "列表测试"),
        ((1, 2), tuple, "元组测试"),
        ({"key": "value"}, dict, "字典测试"),
        ({1, 2, 3}, set, "集合测试"),
    ]
    
    passed_tests = 0
    for value, expected_type, description in test_cases:
        try:
            validate_data(value, expected_type, description)
            print(f"✓ {description} 通过")
            passed_tests += 1
        except Exception as e:
            print(f"✗ {description} 失败: {e}")
    
    print(f"\n测试结果: {passed_tests}/{len(test_cases)} 通过")
    print("所有企业级变量和数据类型最佳实践演示完成!")

if __name__ == "__main__":
    demonstrate_basic_types()
    demonstrate_advanced_operations()
    demonstrate_data_validation()
    demonstrate_type_checking()
    run_comprehensive_tests()